import axios from "axios";
import type { AxiosInstance } from 'axios'
import type { newAxiosRequestConfig } from "./type";
import Storage from "@/utils/Storeage";
import { LOGIN_TOKEN } from "@/global/constants";

// 拦截器：蒙版Loding/token/修改配置
class FYRequest {
  instance: AxiosInstance

  constructor(config: newAxiosRequestConfig) {
    this.instance = axios.create(config)

    // 拦截器:
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        const token = Storage.get(LOGIN_TOKEN)
        if (config.headers && token) {
          config.headers.Authorization = 'Bearer ' + token
        }
        return config
      },
      (error: any) => {
        return Promise.reject(error)
      }
    )

    // 响应拦截器
    this.instance.interceptors.response.use(res => {
      return res.data
    },
      error => {
        // 这里用来处理http常见错误，进行全局提示
        let message: any = "";
        switch (error.response.status) {
          case 400:
            message = "请求错误(400)";
            break;
          case 401:
            message = "未授权，请重新登录(401)";
            // 这里可以做清空storage并跳转到登录页的操作
            break;
          case 403:
            message = "拒绝访问(403)";
            break;
          case 404:
            message = "请求出错(404)";
            break;
          case 408:
            message = "请求超时(408)";
            break;
          case 500:
            message = "服务器错误(500)";
            break;
          case 501:
            message = "服务未实现(501)";
            break;
          case 502:
            message = "网络错误(502)";
            break;
          case 503:
            message = "服务不可用(503)";
            break;
          case 504:
            message = "网络超时(504)";
            break;
          case 505:
            message = "HTTP版本不受支持(505)";
            break;
          default:
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            message = `连接出错(${error.response.status})!`;
        }
        // 这里错误消息可以使用全局弹框展示出来
        // 比如element plus 可以使用 ElMessage
        // ElMessage({
        //   showClose: true,
        //   message: `${message}，请检查网络或联系管理员！`,
        //   type: "error",
        // });
        // 这里是AxiosError类型，所以一般我们只reject我们需要的响应即可
        return Promise.reject(error.response)
      })

    // 对不同 服务请进行拦截
    if (config?.interceptors) {
      this.instance.interceptors.request.use(config.interceptors.requestSuccessFn, config.interceptors.requestFailureFn)
      this.instance.interceptors.response.use(config.interceptors.responseSuccessFn, config.interceptors.responseFailureFn)
    }
  }

  request<T = any>(config: newAxiosRequestConfig): Promise<T> {
    // 针对接口请求的 拦截
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors?.requestSuccessFn(config)
    }

    // 针对接口响应的 拦截
    return new Promise<T>((resolve, reject) => {
      this.instance.request<any, T>(config).then(res => {
        if (config.interceptors?.responseSuccessFn) {
          // res = config.interceptors?.responseSuccessFn(config)
        }
        return resolve(res);
      }).catch(err => {
        return reject(err)
      })
    })
  }

  post(config: newAxiosRequestConfig) {
    return this.request({ ...config, method: 'POST' })
  }

  get<T>(config: newAxiosRequestConfig) {
    return this.request<T>({ ...config, method: 'GET' })
  }

  put(config: newAxiosRequestConfig) {
    return this.request({ ...config, method: 'PUT' })
  }

  delete(config: newAxiosRequestConfig) {
    return this.request({ ...config, method: 'DELETE' })
  }
}

export default FYRequest
